import QtQuick 2.0
import QtQuick.Controls 2.5

/*
规则
兄弟雷的玩法，挖到一个兄弟雷，需要在一个定时周期内再挖开一个地雷，否则这个地雷将会爆炸，游戏失败
同一时刻仅有一个兄弟雷定时自爆，不存在一个定时自爆又挖到另一个兄弟雷。解决一个兄弟雷之后，下一个才会产生

交互
单击翻地，右击挖雷，挖雷次数上限和雷数相同，次数消耗完毕未挖出所有雷游戏失败

兄弟雷在何时生成？
假如有8个地雷，那么最多会有4对兄弟雷，在1次挖雷后，关联1的兄弟雷，开始定时自爆，依次类推3，5，7次挖雷后，分别产生兄弟雷

数据模型
顶层数据存储玩家的操作状态：未打开、打开、挖开

底层数据存储地雷的分布状态：是地雷、邻近雷数
0~8代表雷数，-1代表地雷，-2代表定时地雷
*/

Item {
    property int mineCnt: 8
    property int mineBrotherCnt: mineCnt/4
    property int mineWidth: 8
    property int mineHeight: 8

    property int celMargin: 5

    //cant use in js
//    enum CellState{
//        NotOpen,
//        Opened,
//        Flaged,
//        Boomed
//    }
    property int notOpen: 0
    property int opened: 1
    property int flaged: 2
    property int boomed: 3
    property int unknown: 4

    //状态
    property bool runingGame: false
    property int mineOkCnt: 0
    property int flagCnt: 0
    property int openCnt: 0


    ListModel{
        id:listBrotherMine
    }

    DialogGameOver {
        id: dialogGameOver
        onNewGame: {
            startGame();
        }
    }

    GridView{
        id:gridViewMine
        anchors.fill: parent
        model: modelMine

        cellWidth: parent.width / mineWidth
        cellHeight: parent.height / mineHeight
        delegate: BrotherMineCell{
            width: Math.min(gridViewMine.cellWidth,gridViewMine.cellHeight)
            height: Math.min(gridViewMine.cellWidth,gridViewMine.cellHeight)

            onLeftClicked: {
                if(!runingGame)
                    return ;

                console.log("clicked: row:" + row + "," + col + " index:" + no + " mineState:" + mineState);
                openMine(row,col);

                if(isSuccess())
                    endGame(true);
            }
            onRightClicked: {
                if(!runingGame)
                    return ;

                //如果未打开插旗
                if(notOpen == mineState){
                    mineState = flaged;
                    flagCnt++;
                    if(isMine(mineData))
                        mineOkCnt++;
                }
                //如果是旗子转为问号
                else if(flaged == mineState){
                    mineState = unknown;
                    flagCnt--;
                    if(isMine(mineData))
                        mineOkCnt--;
                }
                //如果是问号取消
                else if(unknown == mineState){
                    mineState = notOpen;
                }

                //检查是否成功
                if(isSuccess())
                    endGame(true);
            }
        }
    }

    ListModel{
        id:modelMine
    }
    Component.onCompleted: {
        startGame();
    }

    function startGame(){
        runingGame = true;
        mineOkCnt = 0;
        flagCnt = 0;
        openCnt = 0;

        resetMineMap(mineWidth,mineHeight);
        calculNearMineCnt();
    }
    function endGame(success){
        runingGame = false;

        if(success){
            console.log("success...");
            dialogGameOver.title = "游戏成功!";
            dialogGameOver.open();
        }else{
            dialogGameOver.title = "游戏失败!";
            dialogGameOver.open();
            console.log("Game Over");
        }
    }

    //生成地图
    function resetMineMap(){
        modelMine.clear();
        for(var i = 0; i < mineWidth*mineHeight; i++){
            modelMine.append({no:i,
                                 nearMineCnt:0,
                                 row:Math.floor(i / mineWidth),
                                 col:i%mineWidth,
                                 mineState:opened,
                                 mineData:0
                             });
        }
        //random mine
        var mineArrIndex = [];
        for(var cnt = 0; cnt < mineCnt; cnt++){
            var index;
            do{
                index = Math.ceil(Math.random()*(modelMine.count-1));
            }while(-1 !== mineArrIndex.indexOf(index));
            mineArrIndex.push(index);

            console.log("mine index:" + index);
            modelMine.setProperty(index,"mineData",-1);
        }

        //生成定时雷的索引

    }

    function calculNearMineCnt(){
        for(var index = 0; index < modelMine.count; index++){
            //is mine
            if(modelMine.get(index).mineData < 0){
                var row = Math.floor(index / mineWidth);
                var col = index % mineWidth;
                console.log("isMine:" + index + " row:" + row + " col:" + col);

                //near ++
                var offsetRow,offsetCol;
                for(offsetRow=-1;offsetRow<2;offsetRow++){
                    for(offsetCol=-1;offsetCol<2;offsetCol++){
                        var nearRow,nearCol;
                        nearRow = row + offsetRow;
                        nearCol = col + offsetCol;

                        //in map
                        if(is_in_map(nearRow,nearCol)){

                            var currentIndex = nearRow * mineWidth + nearCol;
                            //not mine
                            if(modelMine.get(currentIndex).mineData >= 0){
                                var mineCnt = modelMine.get(currentIndex).mineData;
                                mineCnt++;
                                modelMine.setProperty(currentIndex,"mineData",mineCnt);
                            }

//                            console.log("++ nearRow:" + nearRow + " nearCol:" + nearCol + "mineCnt:" + mineCnt);
                        }else{
//                            console.log("!!!!! nearRow:" + nearRow + " nearCol:" + nearCol);
                        }

//                        console.log("for nearRow:" + nearRow + " nearCol:" + nearCol);
                    }
                }

            }
        }
    }

    function openMine(row,col){
        var currentIndex = row * mineWidth + col;
        var mineState = modelMine.get(currentIndex).mineState;

        //isFlag return
        if(flaged === mineState){
            return ;
        }

        //isMine GameOver
        if(isMine(modelMine.get(currentIndex).mineData)){
            modelMine.setProperty(currentIndex,"mineState",boomed);

            endGame(false);
            return ;
        }
        //未打开的置为打开 插旗和已打开都不操作
        else if(notOpen === mineState)
        {
            modelMine.setProperty(currentIndex,"mineState",opened);
            openCnt++;

            //周围0个雷 打开八近邻
            if(0 === modelMine.get(currentIndex).nearMineCnt){
                var offsetRow,offsetCol;
                for(offsetRow=-1;offsetRow<2;offsetRow++){
                    for(offsetCol=-1;offsetCol<2;offsetCol++){
                        var nearRow,nearCol;
                        nearRow = row + offsetRow;
                        nearCol = col + offsetCol;
                        if(is_in_map(nearRow,nearCol)){
                            currentIndex = nearRow * mineWidth + nearCol;
                            openMine(nearRow,nearCol);
                        }
                    }
                }
            }
        }


    }

    function is_in_map(row,col){
        return (row >= 0 && row < mineHeight) && (col >= 0 && col < mineWidth);
    }

    function isSuccess(){

        //打开格子数等于非雷格子数为胜利
        if(openCnt === (mineWidth*mineHeight - mineCnt)){
                console.log(openCnt + "/" + (mineWidth*mineHeight - mineCnt));
            return true;
        }

        //插旗数等于地雷数 并且每一个旗子都插对也为胜利
        if(mineOkCnt === mineCnt && flagCnt === mineCnt){
            console.log(mineOkCnt + "/" + mineCnt + " " + flagCnt + "/" + mineCnt);
            return true;
        }

        return false;
    }

    function isMine(mineData){
        if(mineData < 0)
            return true;
        else
            return false;
    }
}
